package com.wj.crm.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wj.crm.base.BaseService;
import com.wj.crm.dao.CustomerLossMapper;
import com.wj.crm.dao.CustomerMapper;
import com.wj.crm.dao.CustomerOrderMapper;
import com.wj.crm.query.CustomerQuery;
import com.wj.crm.utils.AssertUtil;
import com.wj.crm.utils.PhoneUtil;
import com.wj.crm.vo.Customer;
import com.wj.crm.vo.CustomerLoss;
import com.wj.crm.vo.CustomerOrder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author WangJin
 * @version 1.0
 * @date 2022/1/22 23:29
 */
@Service
public class CustomerService extends BaseService<Customer,Integer> {
    @Resource
    private CustomerMapper customerMapper;

    @Resource
    private CustomerOrderMapper customerOrderMapper;

    @Resource
    private CustomerLossMapper customerLossMapper;

    /**
     * 多条件分页查询客户信息 (BaseService 中有对应的方法)
     * @param query
     * @return
     */
    public Map<String, Object> queryCustomerByParams (CustomerQuery query) {
        Map<String, Object> map = new HashMap<>();
        //开启分页
        PageHelper.startPage(query.getPage(), query.getLimit());
        //得到相应的分页对象
        PageInfo<Customer> pageInfo = new PageInfo<Customer>(customerMapper.selectByParams(query));
        //设置map对象
        map.put("code",0);
        map.put("msg", "success");
        map.put("count", pageInfo.getTotal());
        //设置分页好的列表
        map.put("data", pageInfo.getList());
        return map;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void addCustomer(Customer customer){
        //1.参数校验
        checkCustomerParams(customer.getName(),customer.getFr(),customer.getPhone());
        //2.判断客户名唯一性
        Customer temp = customerMapper.queryCustomerByName(customer.getName());
        //判断客户名是否存在
        AssertUtil.isTrue(null != temp,"客户名已存在，请重新输入！");

        String level = customer.getLevel();
        //System.out.println(level);
        if(level.equals("普通客户")){
            customer.setLevel("1");
        }else if (level.equals("重点开发客户")){
            customer.setLevel("2");
        }else if (level.equals("大客户")){
            customer.setLevel("3");
        }else if (level.equals("合作伙伴")) {
            customer.setLevel("4");
        }

        //2.设置参数的默认值
        customer.setIsValid(1);
        customer.setCreateDate(new Date());
        customer.setUpdateDate(new Date());
        customer.setState(1);

        //客户编号 用当前系统时间
        String khno = "KH" + System.currentTimeMillis();
        customer.setKhno(khno);

        //3.执行添加操作，判断影响行数
        AssertUtil.isTrue(customerMapper.insertSelective(customer) < 1,"添加客户信息失败！");

    }

    private void checkCustomerParams(String name, String fr, String phone) {
        //判断客户名是否为空
        AssertUtil.isTrue(StringUtils.isBlank(name),"请输入客户名！");
        //判断联系人是否为空
        AssertUtil.isTrue(StringUtils.isBlank(fr),"请输入法定联系人！");
        //判断手机号是否为空
        AssertUtil.isTrue(StringUtils.isBlank(phone),"请输入手机号！");
        //手机号  格式是否正确
        AssertUtil.isTrue(!PhoneUtil.isMobile(phone),"手机号格式不正确！");
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateCustomer(Customer customer){
        //1.参数校验
        AssertUtil.isTrue(null == customer.getId(),"待更新记录不存在！");
        //2.通过客户ID查询客户信息
        Customer temp = customerMapper.selectByPrimaryKey(customer.getId());
        //判断客户记录是否存在
        AssertUtil.isTrue(null == temp,"待更新记录不存在！");
        //参数校验
        checkCustomerParams(customer.getName(),customer.getFr(),customer.getPhone());
        //通过客户名称查询客户记录
        temp = customerMapper.queryCustomerByName(customer.getName());
        //判断客户名是否存在（如果数据库客户名存在，修改的客户名和数据库客户名一致且当前更新的客户id与数据库客户id不相同，表示角色名已存在）
        if(null != temp && (customer.getName().equals(temp.getName()) && (!customer.getId().equals(temp.getId())))){
            AssertUtil.isTrue(true,"客户名称已存在，请重新输入！");
            //判断客户信息是否修改（如果数据库客户名存在，修改的客户名和数据库客户名一致且当前更新的客户id与数据库客户id相同时，修改信息没变，表示角色信息未修改）
        }else if( null != temp && (customer.getName().equals(temp.getName())) && (customer.getId().equals(temp.getId())) ){
            AssertUtil.isTrue(customer.getFr().equals(temp.getFr()),"客户信息未修改，请重新输入！");
        }

        String level = customer.getLevel();
        if(level.equals("普通客户")){
            customer.setLevel("1");
        }else if(level.equals("战略合作伙伴")){
            customer.setLevel("2");
        }else if(level.equals("大客户")){
            customer.setLevel("3");
        }else if(level.equals("重点开发客户")){
            customer.setLevel("4");
        }

        //设置参数默认值
        customer.setUpdateDate(new Date());

        //3.执行添加操作，判断影响行数
        AssertUtil.isTrue(customerMapper.updateByPrimaryKeySelective(customer) < 1,"修改客户信息失败！");

    }

    /**
     * 删除客户
     * @param id
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteCustomer(Integer id) {
        //判断id是否为空，数据是否存在
        AssertUtil.isTrue(null == id, "待删除记录不存在！");
        //通过id查询客户记录
        Customer customer = customerMapper.selectByPrimaryKey(id);
        AssertUtil.isTrue(null == customer,"待删除记录不存在！");

        //设置状态为失效
        customer.setIsValid(0);
        customer.setUpdateDate(new Date());

        //执行删除（更新）操作，判断受影响行数
        AssertUtil.isTrue(customerMapper.updateByPrimaryKeySelective(customer) < 1,"删除客户信息失败！");
    }

    /**
     * 更新客户的流失状态
     * 1.查询待流失的客户数据
     * 2.讲流失客户数据批量添加到客户流失表中
     * 3.批量更新新客户的流失状态 0=正常客户 1=流失客户
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateCustomerState(){
        //1.查询待流失的客户数据
        List<Customer> lossCustomerList = customerMapper.queryLossCustomers();
        //2.讲流失客户数据批量添加到客户流失表中
        //判断流失客户是否存在
        if(lossCustomerList != null && lossCustomerList.size() > 0){
            //定义客户流失的列表
            List<CustomerLoss> customerLossList = new ArrayList<>();
            //定义流失客户id
            List<Integer> lossCustomerIds = new ArrayList<>();
            //遍历查询到的流失客户的数据
            lossCustomerList.forEach(customer -> {
                //定义流失客户对象
                CustomerLoss customerLoss = new CustomerLoss();
                //创建时间 系统当前时间
                customerLoss.setCreateDate(new Date());
                //客户经理
                customerLoss.setCusManager(customer.getCusManager());
                //客户名称
                customerLoss.setCusName(customer.getName());
                //客户编号
                customerLoss.setCusNo(customer.getKhno());
                //是否有效  1=有效
                customerLoss.setIsValid(1);
                //修改时间 系统当前时间
                customerLoss.setUpdateDate(new Date());
                //客户最后下单时间
                //通过客户id查询最后订单记录，（最后一条订单记录）
                CustomerOrder customerOrder = customerOrderMapper.queryLossCustomerOrderByCustomerId(customer);
                //判断客户订单是否存在，如果存在，则设置最后下单时间
                if(customerOrder != null){
                    customerLoss.setLastOrderTime(customerOrder.getOrderDate());
                }
                //将流失客户对象设置到对应的集合中
                customerLossList.add(customerLoss);

                //将流失客户的id 设置到对应的集合中
                lossCustomerIds.add(customer.getId());
            });

            // 批量添加流失客户记录
            AssertUtil.isTrue(customerLossMapper.insertBatch(customerLossList) != customerLossList.size(), "客户流失数据转移失败！");

            /* 3. 批量更新客户的流失状态 */
            AssertUtil.isTrue(customerMapper.updateCustomerStateByIds(lossCustomerIds) != lossCustomerIds.size(), "客户流失数据转移失败！");
        }
    }

    /**
     * 查询客户贡献分析
     * @param customerQuery
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    public Map<String,Object> queryCustomerContributionByParams(CustomerQuery customerQuery) {
        Map<String, Object> map = new HashMap<>();

        // 开启分页
        PageHelper.startPage(customerQuery.getPage(), customerQuery.getLimit());
        // 得到对应分页对象
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<Map<String, Object>>(customerMapper.queryCustomerContributionByParams(customerQuery));

        // 设置map对象
        map.put("code",0);
        map.put("msg","success");
        map.put("count",pageInfo.getTotal());
        // 设置分页好的列表
        map.put("data",pageInfo.getList());

        return map;
    }

    /**
     * 查询客户构成 （折线图数据处理）
     * @param
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    public Map<String, Object> countCustomerMake() {
        Map<String, Object> map = new HashMap<>();
        // 查询客户构成数据的列表
        List<Map<String,Object>> dataList = customerMapper.countCustomerMake();
        // 折线图X轴数据  数组
        List<String> data1 = new ArrayList<>();
        // 折线图Y轴数据  数组
        List<Integer> data2 = new ArrayList<>();

        // 判断数据列表 循环设置数据
        if (dataList != null && dataList.size() > 0) {
            // 遍历集合
            dataList.forEach(m -> {
                // 获取"level"对应的数据，设置到X轴的集合中
                data1.add(m.get("level").toString());
                // 获取"total"对应的数据，设置到Y轴的集合中
                data2.add(Integer.parseInt(m.get("total").toString()));
            });
        }

        // 将X轴的数据集合与Y轴的数据集合，设置到map中
        map.put("data1",data1);
        map.put("data2",data2);

        return map;
    }


    /**
     * 查询客户构成 （饼状图数据处理）
     * @param
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    public Map<String, Object> countCustomerMake02() {
        Map<String, Object> map = new HashMap<>();
        // 查询客户构成数据的列表
        List<Map<String,Object>> dataList = customerMapper.countCustomerMake();
        // 饼状图数据   数组（数组中是字符串）
        List<String> data1 = new ArrayList<>();
        // 饼状图的数据  数组（数组中是对象）
        List<Map<String, Object>> data2 = new ArrayList<>();

        // 判断数据列表 循环设置数据
        if (dataList != null && dataList.size() > 0) {
            // 遍历集合
            dataList.forEach(m -> {
                // 饼状图数据   数组（数组中是字符串）
                data1.add(m.get("level").toString());
                // 饼状图的数据  数组（数组中是对象）
                Map<String,Object> dataMap = new HashMap<>();
                dataMap.put("name", m.get("level"));
                dataMap.put("value", m.get("total"));
                data2.add(dataMap);
            });
        }

        // 将X轴的数据集合与Y轴的数据集合，设置到map中
        map.put("data1",data1);
        map.put("data2",data2);

        return map;
    }

}
